package com.example.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.entity.*;
import com.example.mapper.IncomeMapper;
import com.example.mapper.OutcomeMapper;
import com.example.service.IFirstService;
import com.example.service.IIncomeService;
import com.example.service.IOutcomeService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@RestController
@Slf4j
@RequestMapping("/report")
@Tag(name = "分析相关接口")
@CrossOrigin
@RequiredArgsConstructor
public class ReportController {
    @Autowired
    private RedisTemplate redisTemplate;

    private final IIncomeService iIncomeService;
//    @Operation(summary = "计算家庭的恩格尔系数")
//    @GetMapping("/engel")
//    public Result<Double> engel() {
//        log.info("计算恩格尔系数");
//        ValueOperations valueOperations = redisTemplate.opsForValue();
//        if (redisTemplate.hasKey("Engel")) {
//            return Result.success((double) valueOperations.get("Engel"));
//        } else {
//            // TODO 需要获取恩格尔系数并存入redis中
//            double engel = budgetService.getEngel();
//            valueOperations.set("Engel", engel);
//            return Result.success(engel);
//        }
//    }
//      TODO 更新算法
//    @Operation(summary = "对一年的数据进行趋势分析")
//    @GetMapping("/year")
//    public Result<YearAnalysisVO> analysis(LocalDate begin, LocalDate end, int which) {
//        log.info("对一年的数据进行趋势分析");
//        YearAnalysisVO res = budgetService.analysis(begin, end, which);
//        return Result.success(res);
//    }
//
//    @GetMapping("/month")
//    public Result<List<CompareVO>> compare(FirstLabelAnalysisDTO firstLabelAnalysisDTO){
//        log.info("根据月进行对比:{}",firstLabelAnalysisDTO);
//        List<CompareVO> compareVOS = budgetService.compareMonth(firstLabelAnalysisDTO);
//        return Result.success(compareVOS);
//    }
    @GetMapping
    public Result predict() throws IOException, URISyntaxException {
        //获取前十个月的数据
        List<List<CIncome>> res = new ArrayList<>();
        LocalDate now = LocalDate.now();
        LocalDate last = now.plusMonths(-1);
        for (int i = 0; i < 10; i++) {
            List<CIncome> classifiedIncome = iIncomeService.classified(last, now);
            res.add(classifiedIncome);
            now = now.plusMonths(-1);
            last = last.plusMonths(-1);
        }
        //使用HttpClient发送请求到Flask服务器
        CloseableHttpClient httpClient = HttpClients.createDefault();
        //创建请求对象
        URI uri = new URIBuilder()
                .setScheme("http")
                .setHost("localhost:5000")
                .setPath("predict")
                .setParameter("source", JSON.toJSONString(res))
                .build();
        HttpGet httpGet = new HttpGet(uri);
        //发送请求
        CloseableHttpResponse response = httpClient.execute(httpGet);

        // 获得服务端返回的状态码
        int statusCode = response.getStatusLine().getStatusCode();
        System.out.println(statusCode);

        HttpEntity entity = response.getEntity();
        String jsonString = EntityUtils.toString(entity);
        //解析从flask中接受到的参数
        JSONObject jsonObject = new JSONObject(jsonString);

        response.close();
        httpClient.close();

        return Result.success();
    }
    private final IFirstService iFirstService;
    private final IncomeMapper incomeMapper;
    private final IOutcomeService iOutcomeService;
    private final OutcomeMapper outcomeMapper;

    @GetMapping("/predict")
    public Result exportBudgetData(HttpServletResponse response) throws URISyntaxException, IOException {

        // 设置响应内容类型
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        // 设置文件名
        response.setHeader("Content-Disposition", "attachment; filename=\"example.xlsx\"");
        //使用HttpClient发送请求到Flask服务器
        CloseableHttpClient httpClient = HttpClients.createDefault();

        URI uri = new URIBuilder()
                .setScheme("http")
                .setHost("localhost:5000")
                .setPath("predict")
                .build();
        HttpGet httpGet = new HttpGet(uri);
        //发送请求
        CloseableHttpResponse rep = httpClient.execute(httpGet);
        HttpEntity entity = rep.getEntity();
        String res = EntityUtils.toString(entity);

        //获取这个月的开始与结尾
        System.out.println("AAAAAAAAAAAAAAAAAAa");
        LocalDate end = LocalDate.now().withDayOfMonth(1);
        LocalDate begin = end.plusMonths(-1);

        //查询数据
        List<First> firsts = iFirstService.list(new LambdaQueryWrapper<First>()
                .eq(First::getStatus,0));

        //获取准备好的Excel文件格式
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("templates/收支月报.xlsx");
        try {
            // 编辑时间
            XSSFWorkbook excel = new XSSFWorkbook(in);
            XSSFSheet sheet = excel.getSheet("Sheet1");
            sheet.getRow(1).getCell(1).setCellValue("时间：" + begin + "至" + end);
            for (int i = 0; i < firsts.size(); i = i + 3) {
                XSSFRow row = sheet.getRow(3 + i / 3);
                row.getCell(1).setCellValue(firsts.get(i).getTypeName());
                Double d = !firsts.get(i).getJudge() ? incomeMapper.getAmounts(begin,end,firsts.get(i).getId()) : outcomeMapper.getAmounts4(begin,end,firsts.get(i).getId());
                row.getCell(2).setCellValue(d == null ? 0.0 : d);
                if(i + 1 == firsts.size())break;
                row.getCell(3).setCellValue(firsts.get(i + 1).getTypeName());
                d = !firsts.get(i + 1).getJudge() ? incomeMapper.getAmounts(begin,end,firsts.get(i).getId()) : outcomeMapper.getAmounts4(begin,end,firsts.get(i).getId());
                row.getCell(4).setCellValue(d == null ? 0.0 : d);
                if(i + 2 == firsts.size())break;
                row.getCell(5).setCellValue(firsts.get(i + 2).getTypeName());
                d = !firsts.get(i + 2).getJudge() ? incomeMapper.getAmounts(begin,end,firsts.get(i).getId()) : outcomeMapper.getAmounts4(begin,end,firsts.get(i).getId());
                row.getCell(6).setCellValue(d == null ? 0.0 : d);
            }
            List<Income> incomes = iIncomeService.list(new LambdaQueryWrapper<Income>()
                    .between(Income::getTime, begin, end)
                    .orderByAsc(Income::getTime));
            List<Outcome> outcomes = iOutcomeService.list(new LambdaQueryWrapper<Outcome>()
                    .between(Outcome::getTime, begin, end)
                    .orderByAsc(Outcome::getTime));
            for (int i = 0; i < incomes.size(); i++) {
                XSSFRow row = sheet.getRow(10 + i);
                row.getCell(1).setCellValue(incomes.get(i).getTime().toString());
                row.getCell(2).setCellValue(iFirstService.getById(incomes.get(i).getTypeKey()).getTypeName());
                row.getCell(3).setCellValue(incomes.get(i).getAmount());
            }
            for (int i = 0; i < outcomes.size(); i++) {
                XSSFRow row = sheet.getRow(10 + i);
                row.getCell(4).setCellValue(outcomes.get(i).getTime().toString());
                row.getCell(5).setCellValue(iFirstService.getById(outcomes.get(i).getTypeKey1()).getTypeName());
                row.getCell(6).setCellValue(outcomes.get(i).getAmount());
            }

//            String res = "该栏目功能正在开发中";
            //在对应单元格添加分析结果
            sheet.getRow(0).createCell(8).setCellValue(res);
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            // 关闭资源
            out.flush();
            out.close();
            excel.close();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return Result.success();
    }

//    @GetMapping("/info")
//    public Result getInfo(){
//
//    }
}
